#!/usr/bin/env ruby
# -*- coding: binary -*-
#
# Starts the HTTP DB Service interface


require 'pathname'
require Pathname.new(__FILE__).realpath.expand_path.parent.join('config', 'boot')
require 'msf/core/db_manager/http/http_db_manager_service'
require 'optparse'

class HelpError < StandardError; end

class SwitchError < StandardError
  def initialize(msg="Missing required switch.")
    super(msg)
  end
end

def parse_args(args)
  opts = {}
  opt = OptionParser.new
  banner = "msfdb_ws - Metasploit data store as a web service.\n"
  banner << "Usage: #{$0} [options] <var=val>"
  opt.banner = banner
  opt.separator('')
  opt.separator('Options:')

  # Defaults:
  opts[:interface] = '0.0.0.0'
  opts[:port] = 8080
  opts[:ssl] = false
  opts[:ssl_cert] = nil
  opts[:ssl_key] = nil

  opt.on('-i', '--interface  <interface>', String, 'Interface to listen on') do |p|
    opts[:interface] = p
  end

  opt.on('-p', '--port       <port number>', Integer, 'Port to listen on') do |p|
    opts[:port] = p
  end

  opt.on('-s', '--ssl', 'Enable SSL on the server') do |p|
    opts[:ssl] = true
  end

  opt.on('-c', '--cert      <path/to/cert.pem>', String, 'Path to SSL Certificate file') do |p|
    opts[:ssl_cert] = p
  end

  opt.on('-k', '--key       <path/to/key.pem>', String, 'Path to SSL Key file') do |p|
    opts[:ssl_key] = p
  end

  opt.on_tail('-h', '--help', 'Show this message') do
    raise HelpError, "#{opt}"
  end

  begin
    opt.parse!(args)
  rescue OptionParser::InvalidOption => e
    raise UsageError, "Invalid option\n#{opt}"
  rescue OptionParser::MissingArgument => e
    raise UsageError, "Missing required argument for option\n#{opt}"
  end

  opts
end

begin
  opts = parse_args(ARGV)
  raise SwitchError.new("certificate file must be specified when using -s") if opts[:ssl] && (opts[:ssl_cert].nil?)
  HttpDBManagerService.new.start(:Port => opts[:port],
                                 :Host => opts[:interface],
                                 :ssl => opts[:ssl],
                                 :ssl_cert => opts[:ssl_cert],
                                 :ssl_key => opts[:ssl_key])
rescue HelpError => e
  $stderr.puts e.message
end

